package fun.ticsmyc.rpc.common.serializer.impl;

import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;
import fun.ticsmyc.rpc.common.serializer.SerializerCode;
import fun.ticsmyc.rpc.common.exception.SerializeException;
import fun.ticsmyc.rpc.common.serializer.Serializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * 【Hessian编码后数据长度小， 但是性能较低】
 * @author Ticsmyc
 * @date 2020-10-27 10:09
 */
public class HessianSerializer implements Serializer {

    private static final Logger logger= LoggerFactory.getLogger(HessianSerializer.class);

    public final byte ID = SerializerCode.HESSIAN.getCode();

    private HessianSerializer(){}

    private volatile static HessianSerializer INSTANCE=null;

    public static Serializer getInstance() {
        if(INSTANCE == null){
            synchronized (HessianSerializer.class){
                if(INSTANCE == null){
                    INSTANCE = new HessianSerializer();
                }
            }
        }
        return INSTANCE;
    }

    @Override
    public byte[] serialize(Object obj)  {
        HessianOutput hessianOutput= null;
        try{
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            hessianOutput = new HessianOutput(byteArrayOutputStream);
            hessianOutput.writeObject(obj);
            return byteArrayOutputStream.toByteArray();
        }catch(IOException e){
            logger.error("序列化时有错误发生:",e);
            throw new SerializeException("序列化时有错误发生");
        }finally{
            if(hessianOutput != null){
                try {
                    hessianOutput.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public Object deserialize(byte[] bytes, Class<?> clazz) {

        HessianInput hessianInput = null;
        try {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            hessianInput = new HessianInput(byteArrayInputStream);
            return hessianInput.readObject();
        } catch (IOException e) {
            logger.error("序列化时有错误发生:",e);
            throw new SerializeException("序列化时有错误发生");
        }finally{
            if(hessianInput!=null) hessianInput.close();
        }
    }

    @Override
    public byte getId() {
        return ID;
    }


}
